// /////////////////////////////////////////////////////////////////////////////
//
// Name:            AWTEventsContainer.java
// Author:          Michael Bartsch
//
// Desc :           Defines the AWTEventsContainer class.
//
// License:         Copyright (C) 2009 Michael Bartsch
//
//                  This software is provided 'as-is', without any express or
//                  implied warranty. In no event will the authors be held
//                  liable for any damages arising from the use of this
//                  software.
//
//                  Permission is granted to anyone to use this software for
//                  any purpose, including commercial applications, and to
//                  alter it and redistribute it freely, subject to the
//                  following restrictions:
//
//                  1. The origin of this software must not be misrepresented;
//                  you must not claim that you wrote the original software. If
//                  you use this software in a product, an acknowledgment in the
//                  product documentation would be appreciated but is not
//                  required.
//
//                  2. Altered source versions must be plainly marked as such,
//                  and must not be misrepresented as being the original
//                  software.
//
//                  3. This notice may not be removed or altered from any source
//                  distribution.
//
// /////////////////////////////////////////////////////////////////////////////

// Package
package net.dotsimplicity.events.awt;

// Import classes
import net.dotsimplicity.events.*;

import java.awt.Component;
import java.awt.event.*;


// AWTEventsContainer class
/**
 * The AWTEventsContainer is an extension of the {@link EventsContainer} class. This extension
 * wraps AWT's event system in .simplicity's sigslot event system.
 */
public class AWTEventsContainer extends EventsContainer 
                                implements IAWTEventsContainer, 
                                           ActionListener, AdjustmentListener, ComponentListener,
                                           ContainerListener, FocusListener, HierarchyListener, 
                                           HierarchyBoundsListener, ItemListener, MouseListener,
                                           MouseMotionListener, MouseWheelListener, KeyListener,
                                           TextListener, WindowFocusListener, WindowListener, 
                                           WindowStateListener
{
    // Public methods
	/**
	 * Constructs an AWTEventsContainer with the given name and component as base.
	 * @param name           Name of the AWTEventsContainer
	 * @param component      Component to which this class will listen
	 */
	public AWTEventsContainer(String name, Component component)
    {
       // Initialise the object.
	   super(name);
       this.component = component;
    }
	
	public void addActionListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.actionEvents, ActionEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { ActionListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addActionListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.actionEvents);
	   }
	}
	
	public void addAdjustmentListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.adjustmentEvents, AdjustmentEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { AdjustmentListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addAdjustmentListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.adjustmentEvents);
	   }		  
	}
	
	public void addComponentListener()
	{
	   this.createEvents(AWTEventsContainer.componentEvents, ComponentEvent.class);
	   component.addComponentListener(this);
	}
	
	public void addContainerListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.containerEvents, ContainerEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { ContainerListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addContainerListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.containerEvents);
	   }
	}
	
	public void addFocusListener()
	{
	   this.createEvents(AWTEventsContainer.focusEvents, FocusEvent.class);
	   component.addFocusListener(this);
	}
	
	public void addHierarchyBoundsListener()
	{
	   this.createEvents(AWTEventsContainer.hierarchyBoundsEvents, HierarchyEvent.class);
	   component.addHierarchyBoundsListener(this);
	}
	
	public void addHierarchyListener()
	{
	   this.createEvents(AWTEventsContainer.hierarchyEvents, HierarchyEvent.class);
	   component.addHierarchyListener(this);
	}
	
	public void addItemListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.itemEvents, ItemEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { ItemListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addItemListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.itemEvents);
	   }
	}
	
	public void addMouseListener()
	{
	   this.createEvents(AWTEventsContainer.mouseEvents, MouseEvent.class);
	   component.addMouseListener(this);
	}
	
	public void addMouseMotionListener()
	{
		this.createEvents(AWTEventsContainer.mouseMotionEvents, MouseEvent.class);
		component.addMouseMotionListener(this);
	}
	
	public void addMouseWheelListener()
	{
	   this.createEvents(AWTEventsContainer.mouseWheelEvents, MouseEvent.class);
	   component.addMouseWheelListener(this);
	}
	
	public void addKeyListener()
	{
	   this.createEvents(AWTEventsContainer.keyEvents, KeyEvent.class);
	   component.addKeyListener(this);
	}
	
	public void addTextListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.textEvents, TextEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { TextListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addTextListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.textEvents);
	   }
	}
	
	public void addWindowFocusListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.windowFocusEvents, WindowEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addWindowFocusListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.windowFocusEvents);
	   }
	}
	
	public void addWindowListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.windowEvents, WindowEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addWindowListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.windowEvents);
	   }
	}
	
	public void addWindowStateListener()
	{
	   // Create the appropriate slots.
	   this.createEvents(AWTEventsContainer.windowStateEvents, WindowEvent.class);
	   
	   // Try to add this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("addWindowStateListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	      this.removeEvents(AWTEventsContainer.windowStateEvents);
	   }
	}
	
	public void removeActionListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.actionEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { ActionListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeActionListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeAdjustmentListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.adjustmentEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { AdjustmentListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeAdjustmentListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeComponentListener()
	{
	   this.removeEvents(AWTEventsContainer.componentEvents);
	   component.removeComponentListener(this);
	}
	
	public void removeContainerListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.containerEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { ContainerListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeContainerListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeFocusListener()
	{
	   this.removeEvents(AWTEventsContainer.focusEvents);
	   component.removeFocusListener(this);
	}
	
	public void removeHierarchyBoundsListener()
	{
	   this.removeEvents(AWTEventsContainer.hierarchyBoundsEvents);
	   component.removeHierarchyBoundsListener(this);
	}
	
	public void removeHierarchyListener()
	{
	   this.removeEvents(AWTEventsContainer.hierarchyEvents);
	   component.removeHierarchyListener(this);
	}
	
	public void removeItemListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.itemEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { ItemListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeItemListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeMouseListener()
	{
	   this.removeEvents(AWTEventsContainer.mouseEvents);
	   component.removeMouseListener(this);
	}
	
	public void removeMouseMotionListener()
	{
		this.removeEvents(AWTEventsContainer.mouseMotionEvents);
		component.removeMouseMotionListener(this);
	}
	
	public void removeMouseWheelListener()
	{
	   this.removeEvents(AWTEventsContainer.mouseWheelEvents);
	   component.removeMouseWheelListener(this);
	}
	
	public void removeKeyListener()
	{
	   this.removeEvents(AWTEventsContainer.keyEvents);
	   component.removeKeyListener(this);
	}
	
	public void removeTextListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.textEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { TextListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeTextListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeWindowFocusListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.windowFocusEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeWindowFocusListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeWindowListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.windowEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeWindowListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	public void removeWindowStateListener()
	{
	   // Remove the appropriate events.
	   this.removeEvents(AWTEventsContainer.windowStateEvents);
	   
	   // Try to remove this object as a listener.
	   try
	   {
		  Class<?> [] param = { WindowListener.class };
		  Object [] arguments = { this };

	      component.getClass().getMethod("removeWindowStateListener", param).invoke(component, arguments);
	   }
	   catch(Exception e)
	   {
	   }
	}
	
	// Events
	// Action event
	public void actionPerformed(ActionEvent event) { this.emitEventSignal("actionPerformed", event); }
	
	// Adjustment event
	public void adjustmentValueChanged(AdjustmentEvent event) { this.emitEventSignal("adjustmentValueChanged", event); }
	
	// Component events
	public void componentHidden(ComponentEvent event)  { this.emitEventSignal("componentHidden",  event); }
	public void componentMoved(ComponentEvent event)   { this.emitEventSignal("componentMoved",   event); }
	public void componentResized(ComponentEvent event) { this.emitEventSignal("componentResized", event); }
	public void componentShown(ComponentEvent event)   { this.emitEventSignal("componentShown",   event); }
	
	// Container events
	public void componentAdded(ContainerEvent event)   { this.emitEventSignal("componentAdded",   event); }
	public void componentRemoved(ContainerEvent event) { this.emitEventSignal("componentRemoved", event); }
	
	// Focus events
	public void focusGained(FocusEvent event) { this.emitEventSignal("focusGained", event); }
	public void focusLost(FocusEvent event)   { this.emitEventSignal("focusLost",   event); }
	
	// HierarchyBounds events
	public void ancestorMoved(HierarchyEvent event)   { this.emitEventSignal("ancestorMoved",   event); }
	public void ancestorResized(HierarchyEvent event) { this.emitEventSignal("ancestorResized", event); }
	
	// Hierarchy event
	public void hierarchyChanged(HierarchyEvent event) { this.emitEventSignal("hierarchyChanged", event); }
	
	// Item event
	public void itemStateChanged(ItemEvent event) { this.emitEventSignal("itemStateChanged", event); }
	
	// Mouse events
	public void mouseClicked(MouseEvent event)         { this.emitEventSignal("mouseClicked",    event); }
	public void mouseEntered(MouseEvent event)         { this.emitEventSignal("mouseEntered",    event); }
	public void mouseExited(MouseEvent event)          { this.emitEventSignal("mouseExited",     event); }
	public void mousePressed(MouseEvent event)         { this.emitEventSignal("mousePressed",    event); }
	public void mouseReleased(MouseEvent event)        { this.emitEventSignal("mouseReleased",   event); }
	
	public void mouseDragged(MouseEvent event)         { this.emitEventSignal("mouseDragged",    event); }
	public void mouseMoved(MouseEvent event)           { this.emitEventSignal("mouseMoved",      event); }
	
	public void mouseWheelMoved(MouseWheelEvent event) { this.emitEventSignal("mouseWheelMoved", event); }
	
	// Keyboard events
	public void keyPressed(KeyEvent event)  { this.emitEventSignal("keyPressed",  event);  }
	public void keyReleased(KeyEvent event) { this.emitEventSignal("keyReleased", event); }
	public void keyTyped(KeyEvent event)    { this.emitEventSignal("keyTyped",    event); }
	
	// Text event
	public void textValueChanged(TextEvent event) { this.emitEventSignal("textValueChanged", event); }
	
	// Window events
	public void windowGainedFocus(WindowEvent event)  { this.emitEventSignal("windowGainedFocus",  event); }
	public void windowLostFocus(WindowEvent event)    { this.emitEventSignal("windowLostFocus",    event); }
	
	public void windowActivated(WindowEvent event)    { this.emitEventSignal("windowActivated",    event); }
	public void windowClosed(WindowEvent event)       { this.emitEventSignal("windowClosed",       event); }
	public void windowClosing(WindowEvent event)      { this.emitEventSignal("windowClosing",      event); }	
	public void windowDeactivated(WindowEvent event)  { this.emitEventSignal("windowDeactivated",  event); }	
	public void windowDeiconified(WindowEvent event)  { this.emitEventSignal("windowDeiconified",  event); }
	public void windowIconified(WindowEvent event)    { this.emitEventSignal("windowIconified",    event); }
	public void windowOpened(WindowEvent event)       { this.emitEventSignal("windowOpened",       event); }
	
	public void windowStateChanged(WindowEvent event) { this.emitEventSignal("windowStateChanged", event); }

	// Private members
	private Component component;
	
	private static final String [] actionEvents =
	  { "actionPerformed" };
	
	private static final String [] adjustmentEvents =
	  { "adjustmentValueChanged" };
	
	private static final String [] componentEvents =
	  { "componentHidden", "componentMoved", "componentResized", "componentShown" };
	
	private static final String [] containerEvents =
	  { "componentAdded", "componentRemoved" };
	
	private static final String [] focusEvents =
	  { "focusGained", "focusLost" };
	
	private static final String [] hierarchyBoundsEvents =
	  { "ancestorMoved", "ancestorResized" };
	
	private static final String [] hierarchyEvents =
	  { "hierarchyChanged" };
	
	private static final String [] itemEvents =
	  { "itemStateChanged" };
	
	private static final String [] keyEvents = 
	  { "keyPressed", "keyReleased", "keyTyped" };
	
	private static final String [] mouseEvents = 
	  { "mouseClicked", "mouseEntered", "mouseExited", "mousePressed", "mouseReleased" };
	private static final String [] mouseMotionEvents = 
	  { "mouseDragged", "mouseMoved" };
	private static final String [] mouseWheelEvents = 
	  { "mouseWheelMoved" };
	
	private static final String [] textEvents = 
	  { "textValueChanged" };
	
	private static final String [] windowFocusEvents = 
	  { "windowGainedFocus", "windowLostFocus" };
	private static final String [] windowEvents = 
	  { "windowActivated", "windowClosed", "windowClosing", "windowDeactived", 
		"windowDeiconified", "windowIconified", "windowOpened" };
	private static final String [] windowStateEvents = 
	  { "windowStateChanged" };
}

// End of File
